package com.lightboat.common.algorithm;

import com.google.common.cache.LoadingCache;
import com.lightboat.common.utils.StringUtils;

import java.util.List;
import java.util.function.Supplier;

/**
 * 基于Guava Cache的本地缓存抽取系统
 * 主要功能是通过Guava LoadingCache缓存抽取轮盘配置，支持高效的抽取操作。
 */
public class GuavaLotteryService<T> {

    // 缓存抽取轮盘配置，使用LoadingCache实现自动加载和缓存刷新
    private LoadingCache<String, WeightedLotteryWheel<T>> lotteryCache;

    /**
     * 构造函数，初始化时传入自定义的LoadingCache实例
     */
    public GuavaLotteryService(LoadingCache<String, WeightedLotteryWheel<T>> cache) {
        this.lotteryCache = cache;
    }

    /**
     * 从数据库加载抽取配置
     *
     * @param supplier 提供抽取数据列表的Supplier接口
     * @return 构建好的WeightedLotteryWheel实例
     */
    private WeightedLotteryWheel loadLotteryFromDatabase(Supplier<List<WeightedLotteryWheel.Prize<T>>> supplier) {
        // 模拟从数据库加载抽取数据列表并构建抽取轮盘
        List<WeightedLotteryWheel.Prize<T>> prizes = supplier.get();
        return new WeightedLotteryWheel<T>(prizes);
    }

    /**
     * 执行抽取操作
     *
     * @param activityId 活动ID，用于定位具体的抽取轮盘
     * @return 抽中的抽取数据信息
     * @throws RuntimeException 如果抽取失败或缓存获取异常
     */
    public WeightedLotteryWheel.Prize<T> drawPrize(String activityId) {
        activityId = StringUtils.isBlank(activityId) ? "all" : activityId;
        try {
            lotteryCache.refresh(activityId);
            WeightedLotteryWheel<T> lottery = lotteryCache.get(activityId);
            return lottery.drawPrize();
        } catch (Exception e) {
            throw new RuntimeException("抽取失败", e);
        }
    }

    /**
     * 手动刷新缓存（用于活动配置变更）
     *
     * @param activityId 活动ID，用于定位需要刷新的缓存项
     */
    public void refreshLotteryConfig(String activityId) {
        activityId = StringUtils.isBlank(activityId) ? "all" : activityId;
        lotteryCache.refresh(activityId);
    }
}